package org.jash.common.mvi

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.consumeAsFlow
import kotlinx.coroutines.launch
import java.lang.reflect.Method
import java.lang.reflect.Type

open class BaseViewModel<I:BaseIntent,S:BaseState>:ViewModel() {
    val intent: Channel<I> by lazy { Channel(Channel.UNLIMITED) }
    val state: MutableStateFlow<BaseState?> by lazy { MutableStateFlow(null) }
    private val map:Map<Type, Method>
    init {
        map = javaClass.declaredMethods
            .filter { it.parameterTypes.size == 1 }
            .filter { BaseIntent::class.java.isAssignableFrom(it.parameterTypes[0]) }
            .associateBy { it.parameterTypes[0] }
        viewModelScope.launch {
            intent.consumeAsFlow().collect {
                collect(it)
            }
        }
    }
    fun collect(intent:I) {
        map[intent.javaClass]?.invoke(this, intent)
    }
}